package com.itheima.service.impl;

import com.itheima.common.AuthThreadLocal;
import com.itheima.common.CustomException;
import com.itheima.utils.SnowflakeUtils;
import com.itheima.dto.DishFlavorDto;
import com.itheima.dto.SetmealDto;
import com.itheima.entity.*;
import com.itheima.mapper.*;
import com.itheima.service.SetmealService;
import com.itheima.vo.SetmealVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author HeiMa-sw
 * @Description 套餐业务层实现类//TODO 17210
 * @Date 13:43 2022/6/10
 **/
@Service
@EnableCaching
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavorMapper dishFlavorMapper;
    @Autowired
    private SnowflakeUtils snowflakeUtils;

    @Override
    public void saveOne(SetmealDto setmealDto) {
        String empId = AuthThreadLocal.getAuth();
        Setmeal setmeal = new Setmeal();
        getSetMeal(setmealDto, empId, setmeal);
        setmealMapper.insertOne(setmeal);
        //新增到套餐菜品表
        List<SetmealDish> setMealDish = getSetMealDish(setmealDto, empId, setmeal);
        setmealDishMapper.batchInsert(setMealDish);
    }


    @Override
    public SetmealVo getPage(Integer page, Integer pageSize, String name) {
        SetmealVo setmealVo = new SetmealVo();
        setmealVo.setCurrent(page);
        if (page == 1) {
            page = 0;
        } else {
            page = (page - 1) * pageSize;
        }
        List<Setmeal> setmealList = setmealMapper.selectPage(page, pageSize, name);
        List<SetmealDto> setmealDtoList = setmealList.stream().map(setmeal -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(setmeal, setmealDto);
            Category category = categoryMapper.selectById(setmeal.getCategoryId());
            setmealDto.setCategoryName(category.getName());
            setmealDto.setType(category.getType());
            if (setmealDto.getType() == 2) {
                return setmealDto;
            } else {
                return null;
            }
        }).collect(Collectors.toList());
        setmealVo.setRecords(setmealDtoList);
        setmealVo.setSize(pageSize);
        setmealVo.setTotal(setmealMapper.selectCount());
        return setmealVo;
    }

    @Override
    public SetmealDto getById(final String setmealId) {
        Setmeal setmeal = setmealMapper.selectById(setmealId);
        List<SetmealDish> sdList = setmealDishMapper.selectById(setmealId);
        SetmealDto setmealDto = new SetmealDto();
        BeanUtils.copyProperties(setmeal, setmealDto);
        setmealDto.setSetmealDishes(sdList);
        return setmealDto;
    }

    @Override
    public void batchRemove(String[] ids) {
        List<Integer> status = setmealMapper.batchSelectStatus(ids);
        if (status.isEmpty()) {
            setmealMapper.deleteByIds(ids);
        } else {
            throw new CustomException("套餐正在售卖中，不能删除");
        }
    }

    @Override
    public void modifyOne(final SetmealDto setmealDto) {
        String empId = AuthThreadLocal.getAuth();
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDto, setmeal, "flavors");
        setmeal.setUpdateTime(LocalDateTime.now());
        setmeal.setUpdateUser(empId);
        setmealMapper.updateOne(setmeal);
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        setmealDishMapper.deleteBySid(setmeal.getId());
        setmealDishes = setmealDishes.stream().map(setmealDish -> {
            Dish dish = dishMapper.selectByIdOrName(setmealDish.getName());
            setmealDish.setId(String.valueOf(snowflakeUtils.snowflakeId()));
            setmealDish.setDishId(dish.getId());
            return getSetmealDish(empId, setmeal, setmealDish);
        }).collect(Collectors.toList());
        setmealDishMapper.batchInsert(setmealDishes);
    }

    @Override
    public void modifyStatus(final Integer status, final String[] ids) {
        String empId = AuthThreadLocal.getAuth();
        List<Setmeal> setmeals = setmealMapper.selectByIds(ids);
        setmeals = setmeals.stream().map(setmeal -> {
            if (status.equals(1)) {
                setmeal.setStatus(1);
            } else {
                setmeal.setStatus(0);
            }
            setmeal.setUpdateUser(empId);
            setmeal.setUpdateTime(LocalDateTime.now());
            return setmeal;
        }).collect(Collectors.toList());
        setmealMapper.batchUpdateStatus(setmeals);
    }


    /**
     * 获取套餐菜品信息
     *
     * @param empId       员工编号
     * @param setmeal     套餐
     * @param setmealDish 套餐菜品信息
     * @return 套餐菜品
     */
    private SetmealDish getSetmealDish(final String empId, final Setmeal setmeal, final SetmealDish setmealDish) {
        setmealDish.setSetmealId(setmeal.getId());
        setmealDish.setSort(setmealMapper.selectCount() + 1);
        setmealDish.setCreateTime(LocalDateTime.now());
        setmealDish.setUpdateTime(LocalDateTime.now());
        setmealDish.setCreateUser(empId);
        setmealDish.setUpdateUser(empId);
        setmealDish.setIsDeleted(0);
        return setmealDish;
    }

    //获取套餐信息
    private void getSetMeal(final SetmealDto setmealDto, final String empId, final Setmeal setmeal) {
        BeanUtils.copyProperties(setmealDto, setmeal, "setmealDishes");
        setmeal.setId(String.valueOf(snowflakeUtils.snowflakeId()));
        setmeal.setStatus(1);
        setmeal.setCreateTime(LocalDateTime.now());
        setmeal.setUpdateTime(LocalDateTime.now());
        setmeal.setCreateUser(empId);
        setmeal.setUpdateUser(empId);
        setmeal.setIsDelete(0);
    }

    /**
     * 获取套餐数据对象信息
     *
     * @param setmealDto 套餐数据对象
     * @param empId      用户id
     * @param setmeal    套餐
     * @return List<SetmealDish>
     */
    private List<SetmealDish> getSetMealDish(final SetmealDto setmealDto, final String empId, final Setmeal setmeal) {
        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        setmealDishes = setmealDishes.stream().map(a -> {
            SetmealDish setmealDish = new SetmealDish();
            BeanUtils.copyProperties(a, setmealDish);
            setmealDish.setId(String.valueOf(snowflakeUtils.snowflakeId()));
            return getSetmealDish(empId, setmeal, setmealDish);
        }).collect(Collectors.toList());
        return setmealDishes;
    }

    @Override
    @Cacheable(value = "setmealCache",key = "#result")
    public List<SetmealDto> getList(final String categoryId, final Integer status) {
        List<Setmeal> listByCid = setmealMapper.selectListByCid(categoryId);
        Category category = categoryMapper.selectById(categoryId);
        return listByCid.stream().map(setmeal -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(setmeal, setmealDto);
            setmealDto.setType(category.getType());
            if (setmealDto.getStatus().equals(status)) {
                return setmealDto;
            } else {
                return null;
            }
        }).collect(Collectors.toList());
    }

    @Override
    public List<DishFlavorDto> getDishFlavorsList(final String setmealId) {
        List<SetmealDish> setmealDishList = setmealDishMapper.selectById(setmealId);
        return setmealDishList.stream().map(setmealDish -> {
            DishFlavorDto dishFlavorDto = new DishFlavorDto();
            Dish dish = dishMapper.selectByIdOrName(setmealDish.getName());
            BeanUtils.copyProperties(dish, dishFlavorDto);
            Category category = categoryMapper.selectById(dish.getCategoryId());
            dishFlavorDto.setType(category.getType());
            List<DishFlavor> dishFlavorList = dishFlavorMapper.selectByDishId(setmealDish.getDishId());
            dishFlavorDto.setFlavors(dishFlavorList);
            return dishFlavorDto;
        }).collect(Collectors.toList());
    }
}
